(defvar file-list (make-hash-table :test 'equal))
(defvar *postfix-list* '("" ".as" ".xml" ".java" ".pgen"))

(defun for-each-folder (folder body)
  (let* ((dir-list '())
	 (folder (if (null folder) "." folder)))
    (funcall body folder)
    (dolist (file (directory-files folder))
      (catch 'continue
	(when (or (equal file ".") 
		  (equal file ".."))
	  (throw 'continue nil))
	(setq path (concat folder "/" file))
	(when (file-directory-p path)
	  (push path dir-list))))
    (dolist (path dir-list)
      (for-each-folder path body))))

(defun import-files(directory &optional postfix-list)
  "import all files from a workspace"
  (interactive "sdirectory: ")
  (let* ((postfix-list (if (null postfix-list)
			   *postfix-list*
			 postfix-list)))
    (for-each-folder directory
		     (lambda (directory)
		       (dolist (file (directory-files directory))
			 (catch 'continue
			   (setq path (concat directory "/" file))
			   (when (file-directory-p path)
			     (throw 'continue nil))
			   (dolist (postfix postfix-list)
			     (when (string-match postfix file)
			       (setf (gethash file file-list) path)))))))))

(defun open-if-file-exists (filename)
  (catch 'break
    (when (null filename) 
      (throw 'break nil))
    (dolist (postfix (append postfix-list ""))
      (when (file-exists-p (concat filename postfix))
	(find-file (concat filename postfix))
	(throw 'break 't)))
    (throw 'break nil)))



(defun get-file(filename &optional directory)
  "get file"
  (interactive "sfile name: ")
  (let* ((dir-list '())
	 (directory (if (null directory) "." directory)))
    (dolist (postfix (append postfix-list))
      (unless (null (gethash (concat filename postfix) file-list))
	(find-file (gethash (concat filename postfix) file-list))
	(return)))
    (for-each-folder directory 
		     (lambda (directory) 
		       (when (open-if-file-exists (concat directory "/" filename))
			 (return))))))




;(global-set-key (kbd "C-x C-g") 'get-file)

(provide 'get-file)